package com.frinder.astar;

/**
 * Created by kiktech on 2018/2/10.
 */
public class Node implements Comparable<Node> {

    private Point point;

    private Node parentNode;

    /**
     * 从起点到当前结点的实际路径代价
     */
    private double g;

    /**
     * 当前结点到达最终结点的估算代价，估算值为不考虑障碍时理想代价
     */
    private double h;

    /**
     * 是否为障碍物
     */
    private boolean blocked;

    private Node(Builder builder) {
        setPoint(builder.point);
        setParentNode(builder.parentNode);
        setG(builder.g);
        setH(builder.h);
        setBlocked(builder.blocked);
    }

    @Override
    public String toString() {
        return point.toString();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        Node node = (Node) o;

        return point != null ? point.equals(node.point) : node.point == null;
    }

    @Override
    public int hashCode() {
        return point != null ? point.hashCode() : 0;
    }

    @Override
    public int compareTo(Node o) {
        if (null == o) {
            return -1;
        }
        double sf = g + h;
        double df = o.g + o.h;
        if (sf > df) {
            // 降序
            return 1;
        } else if (sf < df) {
            // 升序
            return -1;
        }
        return 0;
    }

    public Point getPoint() {
        return point;
    }

    public void setPoint(Point point) {
        this.point = point;
    }

    public Node getParentNode() {
        return parentNode;
    }

    public void setParentNode(Node parentNode) {
        this.parentNode = parentNode;
    }

    public double getG() {
        return g;
    }

    public void setG(double g) {
        this.g = g;
    }

    public double getH() {
        return h;
    }

    public void setH(double h) {
        this.h = h;
    }

    public boolean isBlocked() {
        return blocked;
    }

    public void setBlocked(boolean blocked) {
        this.blocked = blocked;
    }

    public static final class Builder {
        private Point point;
        private Node parentNode;
        private double g;
        private double h;
        private boolean blocked;

        public Builder() {
        }

        public Builder point(Point val) {
            point = val;
            return this;
        }

        public Builder parentNode(Node val) {
            parentNode = val;
            return this;
        }

        public Builder g(double val) {
            g = val;
            return this;
        }

        public Builder h(double val) {
            h = val;
            return this;
        }

        public Builder blocked(boolean val) {
            blocked = val;
            return this;
        }

        public Node build() {
            return new Node(this);
        }
    }
}
